<html>
    <head>
      <title>directive 用法</title>
      <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    </head>
    <body>
      <div id="root">
        <div v-loading="isLoading">{{data}}</div>
        <button @click="update">更新</button>
        <div>
           <!-- <div :visible="visible">加载中</div> -->对比这类侵入式组件，
           directive可以讲这些通用逻辑封装成静态方法
        </div>
      </div>
      <script>
        //   debugger
        Vue.directive('loading', {
          //当我们的isLoading发生变化的时候会触发update
          //1. 传入的是object
          update(el, binding, vnode) {
            // 会触发两次
            console.log(el, binding, vnode)
            /*
            第一次调用：
            <div></div>
            {name: "loading", rawName: "v-loading", value: true, expression: "isLoading", modifiers: {…},name: "loading"，oldArg: undefined，oldValue: false，rawName: "v-loading"，value: true， …} 
            VNode {tag: "div", data: {…}, children: Array(1), text: undefined, elm: div, …}
            第二次调用：
            <div>用户数据 </div> 
            {name: "loading", rawName: "v-loading", value: false, expression: "isLoading", modifiers: {…},name: "loading"，oldArg: undefined，oldValue: true，rawName: "v-loading"，value: false， …} 
            VNode {tag: "div", data: {…}, children: Array(1), text: undefined, elm: div, …}
            */
            if (binding.value) {
              // 非侵入的创建一个遮罩，可以封装成固定的静态组件
              const div = document.createElement('div')
              div.innerText = '加载中...'
              div.setAttribute('id', 'loading')
              div.style.position = 'absolute'
              div.style.left = 0
              div.style.top = 0
              div.style.width = '100%'
              div.style.height = '100%'
              div.style.display = 'flex'
              div.style.justifyContent = 'center'
              div.style.alignItems = 'center'
              div.style.color = 'white'
              div.style.background = 'rgba(0, 0, 0, .7)'
              document.body.append(div)
            } else {
              document.body.removeChild(document.getElementById('loading'))
            }
          },
        })
        /*
        2.传入的是function
         Vue.directive('loading', {
          update(el, binding, vnode) {
            console.log(el, binding, vnode)
            if (binding.value) {
              const div = document.createElement('div')
              div.innerText = '加载中...'
              div.setAttribute('id', 'loading')
              div.style.position = 'absolute'
              div.style.left = 0
              div.style.top = 0
              div.style.width = '100%'
              div.style.height = '100%'
              div.style.display = 'flex'
              div.style.justifyContent = 'center'
              div.style.alignItems = 'center'
              div.style.color = 'white'
              div.style.background = 'rgba(0, 0, 0, .7)'
              document.body.append(div)
            } else {
              // 因为是function时会直接绑定到bind和update两个生命周期上，当时bind时，我们的loading还没有加入当页面当中，所以会找不到这个dom节点
              const div = document.getElementById('loading')
              div && document.body.removeChild(div)
            }
          },
        })
        */
  
        new Vue({
          el: '#root',
          data() {
            return {
              isLoading: false,
              data: '',
            }
          },
          methods: {
            update() {
              this.isLoading = true
              setTimeout(() => {
                this.data = '用户数据'
                // 获取请求时我们可以使用try catch方法防止未知错误
                this.isLoading = false
              }, 3000)
            },
          },
        })
      </script>
    </body>
  </html>
  
  